/*
 * ikakeibo 0.6.0
 * Copyright (C)2009 wateray and contributors
 * wateray@gmail.com
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

package com.wateray.ipassbook.ui.widget;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Vector;

import javax.swing.AbstractButton;
import javax.swing.GroupLayout;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.LayoutStyle;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

import org.apache.log4j.Logger;

import com.wateray.ipassbook.kernel.event.IPassbookListener;
import com.wateray.ipassbook.kernel.event.IPassbookObserver;
import com.wateray.ipassbook.ui.GuiUtils;
import com.wateray.ipassbook.ui.dialog.ReceiptDialog.Type;
import com.wateray.ipassbook.util.LanguageLoader;
import com.wateray.ipassbook.util.log4j.Log;

/**
 * @author wateray
 * @create 2009-5-6
 */

public abstract class TitleMessageDialog extends JDialog implements IPassbookListener {
	
    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	protected Logger logger = Log.getLogger(this.getClass());
	
	/** titlePanel.*/
    private JPanel titlePanel;
    private JSeparator titleSeparator;
    private JLabel titleLabel;
    private JLabel messageLabel;
    private JLabel iconLabel;
 
    /** buttonPanel.*/
    private JPanel buttonPanel;
    private JSeparator buttonSeparator;
    private JButton finishButton;
    private JButton cancelButton;
    private JButton helpButton;
    
    /** Whether created the buttons or not.*/
    private boolean showFinishButton = true;
    private boolean showCancelButton = true;
    private boolean showHelpButton = true;
    
    
    /** centerPane.*/
    protected JPanel centerPane;
    

	private Hashtable<String,AbstractButton> buttonMap;
    protected Vector<AbstractButton> buttonVector;
    
    private static int BUTTON_PREFERRED_SIZE = 73;
    
    protected String errorMessage = "";
    
	public TitleMessageDialog(Component owner, String title) {
		this(owner, 0, 0, true, title);
		this.setPreferredSize(getPreferredSize());
		

	}
	
    /** Creates new form DialogPanel */
    public TitleMessageDialog(Component owner, int width, int height, boolean modal, String title) {
    	
        setLayout(new BorderLayout());      
        buttonMap = new Hashtable<String, AbstractButton>();   
        buttonVector = new Vector<AbstractButton>();
        setSize(new Dimension(width,height));
        setLocationRelativeTo(owner);
		this.setTitle(title);
        setModalityType(modal? ModalityType.APPLICATION_MODAL:ModalityType.MODELESS);
		setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		
		//addIPassbookListener
		IPassbookObserver.getInstance().addIPassbookListener(this);
		
        initComponents();
		initData();
		initState();
    }

    protected void initState() {
		// TODO Auto-generated method stub
		
	}

    protected void initData() {
		// TODO Auto-generated method stub
		
	}

	/** This method is called from within the constructor to
     * initialize the form.
     */
    private void initComponents() {
    	setTitlePanel(getTitlePanel());
    	setButtonPanel(getButtonPanel());
    	setCenterPane(getCenterPane());
    }
	/**
	 * @param titlePanel the titlePanel to Panel
	 */
    private void setTitlePanel(JPanel titlePanel){
    	 this.add(titlePanel, BorderLayout.PAGE_START);
    }
    
	/**
	 * @param centerPane the centerPane to Panel
	 */
	public void setCenterPane(Component contentPanel) {
		 add(contentPanel, BorderLayout.CENTER);
	}
	
	/**
	 * @param ButtonPanel the centerPane to Panel
	 */
	public void setButtonPanel(JPanel buttonPanel) {
		 add(buttonPanel, BorderLayout.PAGE_END);
	}
	
    private JPanel getTitlePanel(){
    	if(titlePanel == null){
    		titlePanel = new JPanel();
    	    titleSeparator = new JSeparator();
    	    titlePanel.setBackground(new Color(255, 255, 255));
            
            GroupLayout titlePanelLayout = new GroupLayout(titlePanel);
            titlePanel.setLayout(titlePanelLayout);
            titlePanelLayout.setHorizontalGroup(
                titlePanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
                .addGroup(titlePanelLayout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(titlePanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
                        .addComponent(getTitleLabel())
                        .addComponent(getMessageLabel()))
                    .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 411, Short.MAX_VALUE)
                    .addComponent( getIconLabel())
                    .addGap(36, 36, 36))
                .addComponent(titleSeparator, GroupLayout.DEFAULT_SIZE, 589, Short.MAX_VALUE)
            );
            titlePanelLayout.setVerticalGroup(
                titlePanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
                .addGroup(titlePanelLayout.createSequentialGroup()
                    .addGroup(titlePanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
                        .addGroup(titlePanelLayout.createSequentialGroup()
                            .addContainerGap()
                            .addComponent(getTitleLabel())
                            .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                            .addComponent(getMessageLabel()))
                        .addGroup(titlePanelLayout.createSequentialGroup()
                            .addGap(18, 18, 18)
                            .addComponent( getIconLabel())))
                    .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 14, Short.MAX_VALUE)
                    .addComponent(titleSeparator, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
            );
            
    	}
    	
    	return titlePanel;
    }
	
	/**
	 * @param title the title to set titleLabel
	 */
	public void setTitleLabel(String title) {
		if(titleLabel != null){
			titleLabel.setText(title);
		}
	}

	/**
	 * @param set message for messageLabel
	 */
	public void setMessageLabel(String message) {
		setMessageLabel(message,null);
	}
	
	/**
	 * @param set message for messageLabel
	 */
	public void setMessageLabel(String message, Icon icon) {
		if(messageLabel != null){
			messageLabel.setText(message);
			//When error message
			logger.debug(message);
			if(!errorMessage.equals("") && errorMessage.equals(message)){
				messageLabel.setForeground(GuiUtils.errorMessageColor);
			}else{
				messageLabel.setForeground(GuiUtils.getLookAndFeelColor("foregroundColor"));
			}
			if(icon != null){
				messageLabel.setIcon(icon);
			}
			
		}
	}
	
	/**
	 * @param icon the Icon to iconLabel 
	 */
	public void setIconLabel(Icon icon) {
		if(iconLabel != null){
			iconLabel.setIcon(icon);
		}
	}
	
	
	public void putButton(AbstractButton button){
		buttonMap.put(button.getText(), button);
		buttonVector.add(button);

	}
	
	public JComponent getButton(String buttonName){
		return buttonMap.get(buttonName);
	}
	
	/**
	 * @return the buttonPanel
	 */
	private JPanel getButtonPanel() {
		if(buttonPanel == null){
			buttonPanel = new JPanel();   
			buttonSeparator = new JSeparator();
		}
		//refresh layout.
		try{
		    layoutButtonPanel();
		}catch(Exception e){
			e.printStackTrace();
		}
		return buttonPanel;
	}

	protected void layoutButtonPanel(){
		if(showHelpButton){
		  getHelpButton();
		}
		if(showCancelButton){
		  getCancelButton();
		}
		if(showFinishButton){
		  getFinishButton();
		}
		
		//Computing the preferred size.
		 for (int i = buttonVector.size()-1; i >= 0; i--){
			 Dimension size = buttonVector.elementAt(i).getPreferredSize();
			 if(size.width > BUTTON_PREFERRED_SIZE){
				 BUTTON_PREFERRED_SIZE = size.width;
			 }
		 }
		
		GroupLayout buttonPanelLayout = new GroupLayout(buttonPanel);
        buttonPanel.setLayout(buttonPanelLayout);
        GroupLayout.ParallelGroup hGroup = buttonPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING);
        
        hGroup.addComponent(buttonSeparator, GroupLayout.DEFAULT_SIZE, 589, Short.MAX_VALUE);
        
        GroupLayout.SequentialGroup hGroupSeq = buttonPanelLayout.createSequentialGroup();
        hGroupSeq.addContainerGap(429, Short.MAX_VALUE);
        for (int i = buttonVector.size()-1; i >= 0; i--){
        	hGroupSeq.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED);
        	hGroupSeq.addComponent(buttonVector.get(i),GroupLayout.PREFERRED_SIZE, BUTTON_PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE);
        }
        hGroupSeq.addContainerGap();
       
        hGroup.addGroup(GroupLayout.Alignment.TRAILING, hGroupSeq);
        buttonPanelLayout.setHorizontalGroup(hGroup);
        
        
        GroupLayout.ParallelGroup vGroup = buttonPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING);
        
        GroupLayout.SequentialGroup vGroupSeq = buttonPanelLayout.createSequentialGroup();
        vGroupSeq.addComponent(buttonSeparator, GroupLayout.PREFERRED_SIZE, 10, GroupLayout.PREFERRED_SIZE);
        vGroupSeq.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE);
  
        GroupLayout.ParallelGroup vGroupPar = buttonPanelLayout.createParallelGroup(GroupLayout.Alignment.BASELINE);
        
        for (int i = buttonVector.size()-1; i >= 0; i--){
        	vGroupPar.addComponent(buttonVector.get(i));
        }     
        vGroupSeq.addGroup(vGroupPar);
        vGroupSeq.addContainerGap();
        vGroup.addGroup(vGroupSeq);
        
        buttonPanelLayout.setVerticalGroup(vGroup);     		
	}
	/**
	 * @return the cancelButton
	 */
	public JButton getCancelButton() {
		if(cancelButton == null){
			cancelButton = new JButton();
			cancelButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent event) {
					cancelButtonActionPerformed(event);
				}
			});
			
	        cancelButton.setText(LanguageLoader.getString("Cancel"));
	        cancelButton.setToolTipText("Cancel this task.");     
	        putButton(cancelButton);
		}
		return cancelButton;
	}

	/**
	 * @return the finishButton
	 */
	public JButton getFinishButton() {
		if(finishButton == null){
			finishButton = new JButton();
			finishButton.setText(LanguageLoader.getString("Finish"));    
			finishButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent event) {
					finishButtonActionPerformed(event);
				}
			});
			  putButton(finishButton);
		}
		return finishButton;
	}
	
	/**
	 * @return the cancelButton
	 */
	public JButton getHelpButton() {
		if(helpButton == null){
			helpButton = new JButton();
			helpButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent event) {
					helpButtonActionPerformed(event);
				}
			});
			
			helpButton.setText(LanguageLoader.getString("Help"));    
	        putButton(helpButton);
		}
		return helpButton;
	}
	/**
	 * @return the centerPane
	 */
	protected JComponent getCenterPane() {
		if(centerPane == null){
			centerPane = new JPanel();
		}
		return centerPane;
	}


	 public static void main(String[] args) throws InterruptedException {
	        try {
	            // TODO code application logic here
	            SwingUtilities.invokeAndWait(new Runnable() {

	                @Override
	                public void run() {
	                }
	            });
	        } catch (InvocationTargetException ex) {
	           // Logger.getLogger(IPassbook.class.getName()).log(Level.SEVERE, null, ex);
	        }

	    }
	 
	 protected void cancelButtonActionPerformed(ActionEvent event){
       this.dispose(); 
//       IPassbookObserver.getInstance().removeIPassbookListener(this);
	 }
	 
	 protected void helpButtonActionPerformed(ActionEvent event){
       this.dispose();
	 }

	 /** abstract.*/
	 protected abstract void finishButtonActionPerformed(ActionEvent event);

	/**
	 * @return the titleLabel
	 */
	private JLabel getTitleLabel() {
		if(titleLabel == null){
			titleLabel = new JLabel();
		}
		return titleLabel;
	}

	/**
	 * @return the messageLabel
	 */
	private JLabel getMessageLabel() {
		if(messageLabel == null){
		    messageLabel = new JLabel();
		}
		return messageLabel;
	}

	/**
	 * @return the iconLabel
	 */
	private JLabel getIconLabel() {
		if(iconLabel == null){
    	    iconLabel = new JLabel();
    	    iconLabel.setToolTipText(LanguageLoader.getString("Icon_Label"));
		}
		return iconLabel;
	}

	/**
	 * @return the errorMessage
	 */
	public String getErrorMessage() {
		return errorMessage;
	} 
	
	public void setTitle(String title){
		super.setTitle(title);
		if(getTitleLabel().getText().equals("")){
			setTitleLabel(title);
		}
		
	}

	/**
	 * @param showFinishButton the showFinishButton to set
	 */
	public void showFinishButton(boolean b) {
		this.showFinishButton = b;
	}

	/**
	 * @param showCancelButton the showCancelButton to set
	 */
	public void showCancelButton(boolean b) {
		this.showCancelButton = b;
	}

	/**
	 * @param showHelpButton the showHelpButton to set
	 */
	public void showHelpButton(boolean b) {
		this.showHelpButton = b;
	}
	
	public void dispose(){
		super.dispose();
	    IPassbookObserver.getInstance().removeIPassbookListener(this);
	}
}
